package com.vanysoft.framework.utils.wx;


import com.vanysoft.framework.utils.CommonUtil;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;

import java.awt.*;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;


/**
 * @author zhusw
 * @description TODO(请求数据通用类)
 * 2016年2月26日 下午10:46:55
 */
@SuppressWarnings("rawtypes")
public class WeixinUtil {

    // 获取公众号access_token的接口地址（GET）
    public final static String access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
    // 获取企业号access_token的接口地址（GET）
    public final static String access_token_url_qy = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=CorpID&corpsecret=SECRET";
    //	 菜单创建（POST）
    public static String menu_create_url = "https://qyapi.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN&agentid=1";
    /**
     * qyTokenMap:企业号token工厂
     *
     * @since Ver 1.1
     */

    private static Map qyTokenMap = new HashMap();

    /**
     * 发起https请求并获取结果
     *
     * @param requestUrl    请求地址
     * @param requestMethod 请求方式（GET、POST）
     * @param outputStr     提交的数据
     * @return JSONObject(通过JSONObject.get ( key)的方式获取json对象的属性值)
     */
    public static JSONObject HttpRequest(String request, String RequestMethod, String output) {
        JSONObject jsonObject = null;
        StringBuffer buffer = new StringBuffer();
        try {
            //建立连接
            URL url = new URL(request);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setUseCaches(false);
            connection.setRequestMethod(RequestMethod);
            if (output != null) {
                OutputStream out = connection.getOutputStream();
                out.write(output.getBytes("UTF-8"));
                out.close();
            }
            //流处理
            InputStream input = connection.getInputStream();
            InputStreamReader inputReader = new InputStreamReader(input, "UTF-8");
            BufferedReader reader = new BufferedReader(inputReader);
            String line;
            while ((line = reader.readLine()) != null) {
                buffer.append(line);
            }
            //关闭连接、释放资源
            reader.close();
            inputReader.close();
            input.close();
            input = null;
            connection.disconnect();
            jsonObject = JSONObject.fromObject(buffer.toString());
        } catch (Exception e) {
        }
        return jsonObject;
    }

    /**
     * 获取access_token (微信公众号)
     *
     * @param AppID(应用ID)
     * @param AppSecret(应用密钥)
     * @return
     */
    public static AccessToken getAccessToken(String appId, String appSecret) {
        AccessToken accessToken = null;
        //从工厂取得token和末次获取时间
        String token = (String) qyTokenMap.get("token");
//		System.out.println("--------------------"+token);
        Date addTokenTime = (Date) qyTokenMap.get("addTokenTime");
        if (token != null && !"".equals(token)) {
            // 判断有效时间 是否超过2小时
            Date end = new Date();
//			System.out.println("--------------------"+formatDateStr(addTokenTime, "yyyy-MM-dd HH:mm"));
            if ((end.getTime() - addTokenTime.getTime()) / 1000 / 3600 >= 2) {
                // 失效 重新获取
                accessToken = reFetchToken(appId, appSecret);
            } else {
                accessToken = new AccessToken();
                accessToken.setToken(token);
                return accessToken;
            }
        } else {
            accessToken = reFetchToken(appId, appSecret);
        }
        return accessToken;
    }

    /**
     * 获取access_token
     *
     * @param CorpID 企业Id
     * @param SECRET 管理组的凭证密钥，每个secret代表了对应用、通讯录、接口的不同权限；不同的管理组拥有不同的secret
     * @return
     */
    public static AccessToken getAccessTokenQy(String corpID, String secret) {
        AccessToken accessToken = null;
        //从工厂取得token和末次获取时间
        String token = (String) qyTokenMap.get("tokenChat");
//		System.out.println("--------------------"+token);
        Date addTokenTime = (Date) qyTokenMap.get("addTokenTimeChat");
        if (token != null && !"".equals(token)) {
            // 判断有效时间 是否超过2小时
            Date end = new Date();
//			System.out.println("--------------------"+formatDateStr(addTokenTime, "yyyy-MM-dd HH:mm"));
            if ((end.getTime() - addTokenTime.getTime()) / 1000 / 3600 >= 2) {
                // 失效 重新获取
                accessToken = reFetchTokenChat(corpID, secret);
            } else {
                accessToken = new AccessToken();
                accessToken.setToken(token);
                return accessToken;
            }
        } else {
            accessToken = reFetchTokenChat(corpID, secret);
        }
        return accessToken;
    }

    public static String formatDateStr(Date date, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.US);
        try {
            return sdf.format(date);
        } catch (Exception e) {
            System.err.println("Exception caught: " + e.getMessage());
        }
        return null;
    }

    /**
     * Function Name               reFetchToken
     *
     * @param corpID
     * @param secret
     * @return
     * @description TODO(公众号获取accessToken)
     * Modify History:              Date             Programmer       Notes
     * ---------        ---------------  ---------
     * 2016-6-23 下午2:09:00          SharpClaw_x                     Initial
     * *********************************************************************
     */
    private static AccessToken reFetchToken(String appId, String appSecret) {
        String requestUrl = access_token_url.replace("APPID", appId).replace("APPSECRET", appSecret);
        JSONObject jsonObject = HttpRequest(requestUrl, "GET", null);
        AccessToken accessToken = null;
        // 如果请求成功
        if (null != jsonObject) {
            try {
                accessToken = new AccessToken();
                accessToken.setToken(jsonObject.getString("access_token"));
                accessToken.setExpiresIn(jsonObject.getInt("expires_in"));
                qyTokenMap.put("token", accessToken.getToken());
                qyTokenMap.put("addTokenTime", new Date());
                System.out.println("获取token成功:" + jsonObject.getString("access_token") + "————" + jsonObject.getInt("expires_in"));
            } catch (Exception e) {
                accessToken = null;
                // 获取token失败
                String error = String.format("获取token失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
                System.out.println(error);
            }
        }
        return accessToken;
    }

    /**
     * Function Name               reFetchTokenChat
     *
     * @param corpID
     * @param secret
     * @return
     * @description TODO(企业号获取accessToken)
     * Modify History:              Date             Programmer       Notes
     * ---------        ---------------  ---------
     * 2016-6-23 下午2:15:10          SharpClaw_x                     Initial
     * *********************************************************************
     */
    private static AccessToken reFetchTokenChat(String corpID, String secret) {
        String requestUrl = access_token_url_qy.replace("CorpID", corpID).replace("SECRET", secret);
        JSONObject jsonObject = HttpRequest(requestUrl, "GET", null);
        AccessToken accessToken = null;
        // 如果请求成功
        if (null != jsonObject) {
            try {
                accessToken = new AccessToken();
                accessToken.setToken(jsonObject.getString("access_token"));
                accessToken.setExpiresIn(jsonObject.getInt("expires_in"));
                qyTokenMap.put("tokenChat", accessToken.getToken());
                qyTokenMap.put("addTokenTimeChat", new Date());
                System.out.println("获取token成功:" + jsonObject.getString("access_token") + "————" + jsonObject.getInt("expires_in"));
            } catch (Exception e) {
                accessToken = null;
                // 获取token失败
                String error = String.format("获取token失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
                System.out.println(error);
            }
        }
        return accessToken;
    }

    /**
     * 创建菜单
     *
     * @param menu        菜单实例
     * @param accessToken 有效的access_token
     * @param agentid     企业应用的id，整型，可在应用的设置页面查看
     * @return 0表示成功，其他值表示失败
     */
    public static int createMenu(Menu menu, String accessToken) {
        int result = 0;

        // 拼装创建菜单的url
        String url = menu_create_url.replace("ACCESS_TOKEN", accessToken);
        // 将菜单对象转换成json字符串
        String jsonMenu = JSONObject.fromObject(menu).toString();
        // 调用接口创建菜单
        JSONObject jsonObject = HttpRequest(url, "POST", jsonMenu);

        if (null != jsonObject) {
            if (0 != jsonObject.getInt("errcode")) {
                result = jsonObject.getInt("errcode");
                String error = String.format("创建菜单失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
                System.out.println(error);
            }
        }

        return result;
    }

    public static String URLEncoder(String str) {
        String result = str;
        try {
            result = java.net.URLEncoder.encode(result, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 根据内容类型判断文件扩展名
     *
     * @param contentType 内容类型
     * @return
     */
    public static String getFileEndWitsh(String contentType) {
        String fileEndWitsh = "";
        if ("image/jpeg".equals(contentType))
            fileEndWitsh = ".jpg";
        else if ("audio/mpeg".equals(contentType))
            fileEndWitsh = ".mp3";
        else if ("audio/amr".equals(contentType))
            fileEndWitsh = ".amr";
        else if ("video/mp4".equals(contentType))
            fileEndWitsh = ".mp4";
        else if ("video/mpeg4".equals(contentType))
            fileEndWitsh = ".mp4";
        return fileEndWitsh;
    }

    /**
     * 数据提交与请求通用方法
     *
     * @param access_token 凭证
     * @param RequestMt    请求方式
     * @param RequestURL   请求地址
     * @param outstr       提交json数据
     */
    public static int PostMessage(String access_token, String RequestMt, String RequestURL, String outstr) {
        int result = 0;
        RequestURL = RequestURL.replace("ACCESS_TOKEN", access_token);
        System.out.println("2===" + outstr);
        JSONObject jsonobject = WeixinUtil.HttpRequest(RequestURL, RequestMt, outstr);
        System.out.println(jsonobject);
//    	Iterator iterator = jsonobject.keys();
//    	while(iterator.hasNext()){
//        	String key = (String) iterator.next();
//	        String value = jsonobject.getString(key);
//		}
        if (null != jsonobject) {
            if (0 != jsonobject.getInt("errcode")) {
                result = jsonobject.getInt("errcode");
                String error = String.format("操作失败 errcode:{} errmsg:{}", jsonobject.getInt("errcode"), jsonobject.getString("errmsg"));
                System.out.println(error);
            }
        }
        return result;
    }

    /**
     * 数据提交与请求通用方法,正确返回0,错误返回JSON结果
     *
     * @param access_token 凭证
     * @param RequestMt    请求方式
     * @param RequestURL   请求地址
     * @param outstr       提交json数据
     */
    public static String PostMessageReturn(String access_token, String RequestMt, String RequestURL, String outstr) {
        String result = "0";
        if (StringUtils.isEmpty(access_token)) {
            return "access_token为空";
        }
        RequestURL = RequestURL.replace("ACCESS_TOKEN", access_token);
        System.out.println("2===" + outstr);
        JSONObject jsonobject = WeixinUtil.HttpRequest(RequestURL, RequestMt, outstr);
        System.out.println(jsonobject);
//    	Iterator iterator = jsonobject.keys();
//    	while(iterator.hasNext()){
//        	String key = (String) iterator.next();
//	        String value = jsonobject.getString(key);
//		}
        if (null != jsonobject) {
            if (0 != jsonobject.getInt("errcode")) {
                result = jsonobject.toString();
                String error = String.format("操作失败 errcode:{} errmsg:{}", jsonobject.getInt("errcode"), jsonobject.getString("errmsg"));
                System.out.println(error);
            }
        } else {
            result = "调用微信接口返回结果为空";
        }
        return result;
    }

    /**
     * Function Name               getWxUserStatus
     *
     * @param userId
     * @param access_token
     * @return
     * @description (根据用户编号和access_token查询用户在企业号中的状态)
     * Modify History:              Date             Programmer       Notes
     * ---------        ---------------  ---------
     * 2017年9月14日 上午10:48:15          SharpClaw_x                     Initial
     * *********************************************************************
     */
    public static String getWxUserStatus(String userId, String access_token) {

        String get_user = "https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token=" + access_token + "&userid=" + userId;
        String result = CommonUtil.sendGet(get_user);
        JSONObject jsonResult = JSONObject.fromObject(result);
        String errcode = jsonResult.getString("errcode");
        if (StringUtils.equals(errcode, "0")) {
            //人员信息存在企业号中可以获取
            String status = jsonResult.get("status").toString();
            //关注状态: 1=已关注，2=已禁用，4=未关注
            if (StringUtils.equals(status, "1")) {
                return "已关注";
            } else if (StringUtils.equals(status, "2")) {
                return "该人员在企业号中被禁用";
            } else {
                //状态其他认为未关注
                return "该人员未关注企业号";
            }
        } else {
            return "该人员信息不存在企业号中";//则人员信息不存在企业号中,返回{"errcode":60111,"errmsg":"userid not found","department":[],"order":[]}
        }
    }


    /**
     * 数据提交与请求通用方法
     *
     * @param access_token 凭证
     * @param RequestMt    请求方式
     * @param RequestURL   请求地址
     * @param outstr       提交json数据
     */
    public static JSONObject getWeiXinAPIResult(String access_token, String RequestMt, String RequestURL, String outstr) {
        System.out.println("access_token==" + access_token);
        RequestURL = RequestURL.replace("ACCESS_TOKEN", access_token);
        System.out.println("outstr===" + outstr);
        JSONObject jsonobject = null;
        jsonobject = WeixinUtil.HttpRequest(RequestURL, RequestMt, outstr);
        System.out.println(jsonobject);
        return jsonobject;
    }

//    public static void main(String[] args) {
//    	
//    	String contentStr="<a href='http://m.baidu.com/'>百度一下,你就知道</a>";
////    	String str =" { "+
////				"\"touser\":\"15821921595\","+
////				"\"toparty\":\"\","+
////				"\"totag\":\"null\","+
////				"\"msgtype\":\"text\"," +
////				"\"agentid\":63," +
////				"\"text\": {" +
////				"\"content\":\""+contentStr+"\""+
////				"} "+
////				" } ";
//    	StringBuffer sb =new StringBuffer();
//    	sb.append("		{                                                                                                                          ");
//    	sb.append("		    \"touser\": \"15821921595\",                                                                                           ");
//    	sb.append("		    \"toparty\": \"\",                                                                                                     ");
//    	sb.append("		    \"totag\": \"\",                                                                                                       ");
//    	sb.append("		    \"msgtype\": \"news\",                                                                                                 ");
//    	sb.append("		    \"agentid\": \"63\",                                                                                                   ");
//    	sb.append("		    \"news\": {                                                                                                            ");
//    	sb.append("		        \"articles\": [                                                                                                    ");
//    	sb.append("		            {                                                                                                              ");
//    	sb.append("		                \"picurl\": \"http://vanyapp.com:8110/upload/f3227081-123d-4ccc-b467-c2470518ab0c.jpg\",  ");
//    	sb.append("		                \"btntxt\": \"查看详情\",                                                                                  ");
//    	sb.append("		                \"description\": \"测试外链摘要\",                                                                         ");
//    	sb.append("		                \"title\": \"测试外链标题\",                                                                               ");
//    	sb.append("		                \"url\": \"https://www.baidu.com/\"                                                                        ");
//    	sb.append("		            }                                                                                                              ");
//    	sb.append("		        ]                                                                                                                  ");
//    	sb.append("		    }                                                                                                                      ");
//    	sb.append("		}                                                                                                                          ");
//    	
//    	String outstr="{\"touser\":\"15821921591\",\"msgtype\":\"news\",\"agentid\":\"63\"," +
//				"\"news\":{\"articles\":[{\"title\":\"测试外链标题\",\"description\":\"测试外链摘要\"," +
//				"\"url\":\"https://www.baidu.com\"," +
//				"\"picurl\":\"http://vanyapp.com:8110/upload/f3227081-123d-4ccc-b467-c2470518ab0c.jpg\"}]" +
//				"	}" +
//				"}";
//    	String str=outstr.toString();
//    	//获取token
//    	
//    	
//		String access_token = getAccessTokenQy("wxde9f2d906c77e909","166iP8z37svsZ3A5Hbq6f8D7jcaPVW56nFPLBNhQVzAQdKrovQq0mmqZSGxCQhiS").getToken();
//		String send_news_msg="https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=ACCESS_TOKEN";
//
//		String get_user="https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token="+access_token+"&userid=15800304255";
//		String result=CommonUtil.sendGet(get_user);
//		JSONObject jsonResult = JSONObject.fromObject(result);
//		System.out.println(jsonResult.get("errcode"));
////		int result =PostMessage(access_token, "POST", send_news_msg, str);
////		System.out.println(access_token + " >>>>>" + str);
//		System.out.println("result="+result);
//		
//	}
}  
